using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Leap
{
	public class DeviceList : Interface, IEnumerable<Device>, IEnumerable
	{
		private class DeviceListEnumerator : IEnumerator<Device>, IDisposable, IEnumerator
		{
			private DeviceList _list;

			private int _index;

			public Device Current => _list._operator_get(_index);

			object IEnumerator.Current
			{
				get
				{
					return Current;
				}
			}

			public DeviceListEnumerator(DeviceList list)
			{
				_list = list;
				_index = -1;
			}

			public void Reset()
			{
				_index = -1;
			}

			public bool MoveNext()
			{
				_index++;
				return _index < _list.Count;
			}

			public void Dispose()
			{
			}
		}

		private HandleRef swigCPtr;

		public Device this[int index]
		{
			get
			{
				return _operator_get(index);
			}
		}

		public int Count => LeapPINVOKE.DeviceList_Count_get(swigCPtr);

		public bool IsEmpty => LeapPINVOKE.DeviceList_IsEmpty_get(swigCPtr);

		public DeviceList(IntPtr cPtr, bool cMemoryOwn)
			: base(LeapPINVOKE.DeviceList_SWIGUpcast(cPtr), cMemoryOwn)
		{
			swigCPtr = new HandleRef(this, cPtr);
		}

		public static HandleRef getCPtr(DeviceList obj)
		{
			return obj?.swigCPtr ?? new HandleRef(null, IntPtr.Zero);
		}

		~DeviceList()
		{
			Dispose();
		}

		public override void Dispose()
		{
			lock (this)
			{
				if (swigCPtr.Handle != IntPtr.Zero)
				{
					if (base.swigCMemOwn)
					{
						base.swigCMemOwn = false;
						LeapPINVOKE.delete_DeviceList(swigCPtr);
					}
					swigCPtr = new HandleRef(null, IntPtr.Zero);
				}
				GC.SuppressFinalize(this);
				base.Dispose();
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		public IEnumerator<Device> GetEnumerator()
		{
			return new DeviceListEnumerator(this);
		}

		public DeviceList()
			: this(LeapPINVOKE.new_DeviceList(), true)
		{
		}

		private Device _operator_get(int index)
		{
			return new Device(LeapPINVOKE.DeviceList__operator_get(swigCPtr, index), true);
		}

		public DeviceList Append(DeviceList other)
		{
			DeviceList result = new DeviceList(LeapPINVOKE.DeviceList_Append(swigCPtr, getCPtr(other)), false);
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}
	}
}
